package com.objecteffects.template.web.action;

import com.google.inject.Inject;

import com.objecteffects.template.model.UserEntity;
import com.objecteffects.template.service.UserEntityService;
import com.objecteffects.template.util.logger.InjectLogger;
import com.objecteffects.template.web.utils.PasswordTypeConverter;

import org.apache.commons.lang3.StringUtils;

import org.slf4j.Logger;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidationErrorHandler;
import net.sourceforge.stripes.validation.ValidationErrors;
import net.sourceforge.stripes.validation.ValidationMethod;

/**
 * @author Rusty Wright
 */
public class UserRegisterActionBean extends BaseActionBean implements
ValidationErrorHandler {
    @InjectLogger
    private Logger log;

    private static final String VALID_CHARS;

    private final UserEntityService userEntityService;

    // @ValidateNestedProperties({
    // @Validate(field = "userName", required = true),
    // @Validate(field = "password", required = true,
    // converter = PasswordTypeConverter.class)
    // })
    // private UserEntity user;

    @Validate(required = true)
    private String userName;

    @Validate(required = true, converter = PasswordTypeConverter.class)
    private String password;

    @Validate(required = true, converter = PasswordTypeConverter.class)
    private String confirmPassword;

    static {
        final String alpha = "abcdefghijklmnopqrstuvwxyz";
        final String digits = "01234567890";

        VALID_CHARS = alpha + alpha.toUpperCase() + digits + "_";
    }

    @Inject
    UserRegisterActionBean(final UserEntityService _userEntityService) {
        this.userEntityService = _userEntityService;
    }

    @SuppressWarnings("static-method")
    @DontValidate
    @DefaultHandler
    public Resolution startHandler() throws Exception {
        return new ForwardResolution(TemplateView.REGISTER_START);
    }

    @DontValidate
    public Resolution cancel() {
        this.log.debug("cancel");

        return new RedirectResolution(this.getClass());
    }

    public Resolution register() {
        this.log.debug("register");

        final UserEntity user = new UserEntity(this.userName, this.password);

        this.userEntityService.save(user);

        return new ForwardResolution(TemplateView.REGISTER_COMPLETE);
    }

    // /**
    // * @return the user
    // */
    // public UserEntity getUser() {
    // return this.user;
    // }

    // /**
    // * @param user
    // * the user to set
    // */
    // public void setUser(final UserEntity _user) {
    // this.user = _user;
    // }

    /**
     * @return the userName
     */
    public String getUserName() {
        return this.userName;
    }

    /**
     * @param _userName
     *        the userName to set
     */
    public void setUserName(final String _userName) {
        this.userName = _userName;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return this.password;
    }

    /**
     * @param _password
     *        the password to set
     */
    public void setPassword(final String _password) {
        this.password = _password;
    }

    /**
     * @return the confirmPassword
     */
    public String getConfirmPassword() {
        return this.confirmPassword;
    }

    /**
     * @param _confirmPassword
     *        the confirmPassword to set
     */
    public void setConfirmPassword(final String _confirmPassword) {
        this.confirmPassword = _confirmPassword;
    }

    @ValidationMethod
    public void validateUsernameAndPasswords(final ValidationErrors errors) {
        // final String username = this.user.getUserName();

        if (this.userEntityService.findByUserName(this.userName) != null) {
            errors.addGlobalError(new SimpleError(this.userName +
                " is already taken."));
        }

        if (this.password.compareTo(this.confirmPassword) != 0) {
            errors
            .addGlobalError(new SimpleError("The passwords do not match."));
        }

        if (!StringUtils.containsOnly(this.userName,
                                      UserRegisterActionBean.VALID_CHARS)) {
            errors.addGlobalError(new SimpleError(
                "Names may contain only letters, digits, and underscore."));
        }
    }

    @Override
    public Resolution handleValidationErrors(final ValidationErrors errors) {
        if (errors.hasFieldErrors()) {
            errors.addGlobalError(new SimpleError("All fields are required."));
        }
        return null;
    }
}
